package com.example.jegotrip.utils;

import android.util.Log;
import java.util.Locale;

/**
 * Log.v()（Verbose）
 * Log.d()（Debug）
 * Log.i()（Info）
 * Log.w()（Warning）
 * Log.e()（Error）
 * Stack Overflow 的实战建议：
 *
 * Log.e：用于捕获“真正”的错误，比如异常捕获块中。
 * Log.w：用于捕获“可疑”但不至于崩溃的情况。
 * Log.i：表示成功或信息性的状态，如连接成功。
 * Log.d：用于调试，打印变量、执行流程等。
 * Log.v：用于“疯狂”式的日志输出，记录非常详细的信息。这个信息可以用来最大程度的登记我们的信息
 */
public class LogUtil {
    private static boolean LOGV = true;
    private static boolean LOGD = true;
    private static boolean LOGI = true;
    private static boolean LOGW = true;
    private static boolean LOGE = true;
    public static void v(String tag, String mess) {
        if (LOGV) { Log.v(tag, mess); }
    }
    public static void d(String tag, String mess) {
        if (LOGD) { Log.d(tag, mess); }
    }
    public static void i(String tag, String mess) {
        if (LOGI) { Log.i(tag, mess); }
    }
    public static void w(String tag, String mess) {
        if (LOGW) { Log.w(tag, mess); }
    }
    public static void e(String tag, String mess) {
        if (LOGE) { Log.e(tag, mess); }
    }
    private static String getTag() {
        StackTraceElement[] trace = new Throwable().fillInStackTrace().getStackTrace();
        String callingClass = "";
        for (int i = 2; i < trace.length; i++) {
            Class<?> clazz = trace[i].getClass();
            if (!clazz.equals(LogUtil.class)) {
                callingClass = trace[i].getClassName();
                callingClass = callingClass.substring(callingClass.lastIndexOf('.') + 1);
                break;
            }
        }
        return callingClass;
    }
    public static void v1(String mess) {
        if (LOGV) { Log.v(getTag(), mess); }
    }
    public static void d1(String mess) {
        if (LOGD) { Log.d(getTag(), mess); }
    }
    public static void i1(String mess) {
        if (LOGI) { Log.i(getTag(), mess); }
    }
    public static void w1(String mess) {
        if (LOGW) { Log.w(getTag(), mess); }
    }
    public static void e1(String mess) {
        if (LOGE) { Log.e(getTag(), mess); }
    }
    private static String buildMessage(String msg) {
        StackTraceElement[] trace = new Throwable().fillInStackTrace().getStackTrace();
        String caller = "";
        for (int i = 2; i < trace.length; i++) {
            Class<?> clazz = trace[i].getClass();
            if (!clazz.equals(LogUtil.class)) {
                caller = trace[i].getMethodName();
                break;
            }
        }
        return String.format(Locale.US, "[%d] %s: %s", Thread.currentThread().getId(), caller, msg);
    }
    public static void v2(String mess) {
        if (LOGV) { Log.v(getTag(), buildMessage(mess)); }
    }
    public static void d2(String mess) {
        if (LOGD) { Log.d(getTag(), buildMessage(mess)); }
    }
    public static void i2(String mess) {
        if (LOGI) { Log.i(getTag(), buildMessage(mess)); }
    }
    public static void w2(String mess) {
        if (LOGW) { Log.w(getTag(), buildMessage(mess)); }
    }
    public static void e2(String mess) {
        if (LOGE) { Log.e(getTag(), buildMessage(mess)); }
    }
    private static String getFunctionName() {
        StackTraceElement[] sts = Thread.currentThread().getStackTrace();
        if (sts != null) {
            for (StackTraceElement st : sts) {
                if (st.isNativeMethod()) {
                    continue;
                }
                if (st.getClassName().equals(Thread.class.getName())) {
                    continue;
                }
                if (st.getClassName().equals(LogUtil.class.getName())) {
                    continue;
                }
                return "[ Thread:" + Thread.currentThread().getName() + ", at " + st.getClassName() + "." + st.getMethodName()
                        + "(" + st.getFileName() + ":" + st.getLineNumber() + ") ]";
            }
        }
        return null;
    }
    private static String getMsgFormat(String msg) {
        return msg + " ;" + getFunctionName();
    }
    public static void v3(String mess) {
        if (LOGV) { Log.v(getTag(), getMsgFormat(mess)); }
    }
    public static void d3(String mess) {
        if (LOGD) { Log.d(getTag(), getMsgFormat(mess)); }
    }
    public static void i3(String mess) {
        if (LOGI) { Log.i(getTag(), getMsgFormat(mess)); }
    }
    public static void w3(String mess) {
        if (LOGW) { Log.w(getTag(), getMsgFormat(mess)); }
    }
    public static void e3(String mess) {
        if (LOGE) { Log.e(getTag(), getMsgFormat(mess)); }
    }
}